package com.java3_21;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class java3_21 {
    //    public static void main(String[] args) {
//        Source source = new Source(1);
//
//        for (int i = 0; i < 5; i++) {
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    source.PrintAA();
//                }
//            }, "线程1").start();
//
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    source.PrintBB();
//                }
//            }, "线程2").start();
//
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    source.PrintCC();
//                }
//            }, "线程3").start();
//        }
//
//
//    }
//    public static void main(String[] args) {
//        //集合中的线程安全问题
//
//        //List
//        /*
//        (1)使用Vector
//        （2）使用Collections工具类
//        （3）创建CopyOnWriteArrayList
//        * */
//
//        //List list = new Vector();
//        //安全的原因为所以的方法都使用了synchronized包裹
//
//
////        ArrayList<Object> list = new ArrayList<>();
////        List<Object> list1 = Collections.synchronizedList(list);
////        list1.add()
//
////        List<Object> objects = Collections.synchronizedList(new ArrayList<>());
//
//
//        //使用的方法可以是里面的方法全部synchronized包裹
//
//        //使用创建CopyOnWriteArrayList
//
////        CopyOnWriteArrayList<Object> objects = new CopyOnWriteArrayList<>();
//        //实现了读写分离
//
//
//        //Set - Collections + CopyOnWriteArraySet
////        Set<Object> objects = Collections.synchronizedSet(new HashSet<>());
//
////        CopyOnWriteArraySet<Object> objects = new CopyOnWriteArraySet<>();
//        //
//
//        //Map -- Collections + concurrentHashMap
////        Map<Object, Object> objectObjectMap = Collections.synchronizedMap(new HashMap<>());
//
////        ConcurrentHashMap<Object, Object> objectObjectConcurrentHashMap = new ConcurrentHashMap<>();
//    }
//    public static void main(String[] args) {
//        //公平锁和非公平锁
//
//        Ticket ticket = new Ticket();
//
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                while (true) {
//                    ticket.PrintAA();
//                }
//            }
//        }, "AA-----").start();
//
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                while (true) {
//                    ticket.PrintBB();
//                }
//            }
//        }, "BB------").start();
//
//
//    }
//    public static void main(String[] args) {
//        //可重入锁 + 不可重入锁
//        //可重入锁 -- 就是拿到该类型的锁的时候还能拿去该类型的锁
//        //
//        Demo1 demo1 = new Demo1();
//
//        //synchronized是可重入锁
//
//        //Lock也是可重入锁
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                demo1.Print();
//            }
//        }).start();
//
//
//
//
//    }
//    public static void main(String[] args) {
////        CallableThread callableThread = new CallableThread();
////        FutureTask futureTask = new FutureTask(callableThread);
////        Thread thread = new Thread(futureTask);
////        thread.start();
////
////        try {
////            int ret = (int)futureTask.get();
////            System.out.println(futureTask.isDone());
////            System.out.println(ret);
////        } catch (InterruptedException e) {
////            throw new RuntimeException(e);
////        } catch (ExecutionException e) {
////            throw new RuntimeException(e);
////        }
//
//
////        new Thread(new FutureTask<>(new Callable<Object>() {
////            @Override
////            public Object call() throws Exception {
////                System.out.println("This is a test !");
////                return null;
////            }
////        }),"线程1").start();
//
//
//    }
//    public static void main(String[] args) {
//        //使用Callable接口创建线程 -- 可以有返回值并且可以抛出异常
//
//        //常用的三个JUC辅助类
//        //1.CountDownLatch  --  在其他线程都结束后在执行某线程
//
////        CountDownLatch countDownLatch = new CountDownLatch(5);
////
////        for (int i = 1; i <= 6; i++) {
////            new Thread(() -> {
////                System.out.println(Thread.currentThread().getName() + "开始执行");
////                try {
////                    Thread.sleep(1000);
////                } catch (InterruptedException e) {
////                    throw new RuntimeException(e);
////                }
////                System.out.println(Thread.currentThread().getName() + "执行结束-----");
////                countDownLatch.countDown();
////            }, String.valueOf(i)).start();
////        }
////
////        //可以使用join方法
////        try {
////            countDownLatch.await();
////        } catch (InterruptedException e) {
////            throw new RuntimeException(e);
////        }
////        System.out.println(Thread.currentThread().getName() + "所以线程全部执行完毕!!!");
////
////    }
//
//
//        //CyclicBarrier - 将线程全部阻塞到某位置后统一释放
//
//
////        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
////            @Override
////            public void run() {
////                System.out.println("全部线程结束");
////            }
////        });
////        for (int i = 1; i <= 5; i++) {
////            int number = i;
////            new Thread(new Runnable() {
////                @Override
////                public void run() {
////                    System.out.println(Thread.currentThread().getName() + "开始执行");
////                    try {
////                        cyclicBarrier.await();
////                    } catch (InterruptedException e) {
////                        throw new RuntimeException(e);
////                    } catch (BrokenBarrierException e) {
////                        throw new RuntimeException(e);
////                    }
////                    System.out.println(number);
////                }
////            }, String.valueOf(i)).start();
////        }
//
//        //Semaphore - 限制线程执行的个数
//
////        Semaphore semaphore = new Semaphore(3);
////        for (int i = 1; i <= 10; i++) {
////            new Thread(new Runnable() {
////                @Override
////                public void run() {
////                    try {
////                        //限制线程只能同时进行3个
////                        semaphore.acquire();
////                    } catch (InterruptedException e) {
////                        throw new RuntimeException(e);
////                    }
////                    System.out.println(Thread.currentThread().getName() + "开始执行");
////                    try {
////                        Thread.sleep(1000);
////                    } catch (InterruptedException e) {
////                        throw new RuntimeException(e);
////                    }
////                    System.out.println(Thread.currentThread().getName() + "执行结束-------");
////                    semaphore.release();
////                }
////            }, String.valueOf(i)).start();
////        }
//
//
//
//
//
//    }
//    public static void main(String[] args) {
//        //读写锁
//        ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//        ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
//        ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
//        ArrayList<Integer> list = new ArrayList<>();
//
//        CountDownLatch countDownLatch = new CountDownLatch(1);
//
//        //占有读锁之后不能在占有写锁
//        for (int i = 1; i <= 5; i++) {
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    try {
//                        countDownLatch.await();
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                    readLock.lock();
//                    try {
//                        System.out.println(Thread.currentThread().getName() + " : " + list);
//                    } finally {
//                        readLock.unlock();
//                    }
//                }
//            }, String.valueOf(i)).start();
//        }
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                writeLock.lock();
//                try {
//                    Integer[] arrNumber = new Integer[10];
//                    for (int i = 0; i < arrNumber.length; i++) {
//                        arrNumber[i] = i;
//                    }
//                    List<Integer> list1 = Arrays.asList(arrNumber);
//                    list.addAll(list1);
//                    System.out.println("写入成功");
//                    countDownLatch.countDown();
//                } finally {
//                    writeLock.unlock();
//                }
//            }
//        }, "写入线程").start();
//
//
//
//
//    }
    public static void main(String[] args) {
        //写锁降级为读锁，但是不能反过来
//        ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//
//        //锁降级 - 获取写锁 + 获取读锁 + 释放写锁
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                int number = 0;
//                reentrantReadWriteLock.writeLock().lock();
//                try {
//                    number = 100;
//                    reentrantReadWriteLock.readLock().lock();
//                } finally {
//                    reentrantReadWriteLock.writeLock().unlock();
//                }
//                try{
//                    System.out.println(number);
//                }finally {
//                    reentrantReadWriteLock.readLock().unlock();
//                }
//            }
//        }).start();

        //阻塞队列 - 自动的阻塞和唤醒 - 常用与生产者和消费者模式
        //两个常用的实现类 - ArrayBlockingQueue + LinkedBlockingQueue

//        ArrayBlockingQueue<Integer> arr = new ArrayBlockingQueue<Integer>(3);
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                while (true) {
//                    try {
//                        arr.put(123);
//                        System.out.println("存入数据");
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//            }
//        },"生产者").start();
//
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                while (true) {
//                    try {
//                        Integer take = arr.take();
//                        System.out.println("拿出数据-------");
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//            }
//        },"消费者").start();


        //阻塞队列
        ArrayBlockingQueue<Integer> arr = new ArrayBlockingQueue<>(3);

        //创建生产者和消费者
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            arr.put(123);
                            System.out.println(Thread.currentThread().getName() + "存入数据");
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }, "生产者 ：" + String.valueOf(i)).start();
        }

        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            Object take = arr.take();
                            System.out.println(Thread.currentThread().getName() + "拿出数据-------");
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }, "消费者" + String.valueOf(i)).start();
        }


    }


}
